package com.wedimob.slideshare.video;

import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.CookieStore;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.BasicHttpContext;

import com.google.gson.Gson;

public class JavaTedDownloader extends JavaVideoDownloader {

    private String url;

    public JavaTedDownloader(String url, String outputDir) {
        this.url = url;
        this.outputDir = outputDir;
    }

    private static class JSONArgsResponse {
        public String file;
        public String id;
    }

    private static class JSONResponse {
        public List<JSONArgsResponse> htmlStreams;
    }

    @Override
    protected Map<String, String> getUrls() {
        try {
            if (info != null) {
                Map<String, String> result = new HashMap<String, String>();
                for (String quality : info.sizes.keySet()) {
                    result.put(quality, humanReadableByteCount(info.sizes.get(quality), false));
                }
                return result;
            }

            info = new VideoInfo();
            CookieStore cookieStore = new BasicCookieStore();
            info.encoding = "UTF-8";
            info.userAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13";
            info.videoId = url;
            info.localContext = new BasicHttpContext();
            info.localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
            info.httpclient = new DefaultHttpClient();
            info.urls = new HashMap<String, String>();

            HttpGet httpget = new HttpGet(info.videoId);
            httpget.setHeader("User-Agent", info.userAgent);
            HttpResponse response = info.httpclient.execute(httpget,
                    info.localContext);
            HttpEntity entity = response.getEntity();
            if (entity != null && response.getStatusLine().getStatusCode() == 200) {
                InputStream instream = entity.getContent();
                String videoInfo = getStringFromInputStream(info.encoding, instream);
                if (videoInfo != null && videoInfo.length() > 0) {

                    int beginIndex = videoInfo.indexOf("var talkDetails = ");
                    int endIndex = videoInfo.indexOf("}</", beginIndex + 18);
                    String json = videoInfo
                            .substring(beginIndex + 18, endIndex + 1);
                    Gson gson = new Gson();
                    JSONResponse jsonObj = gson.fromJson(json, JSONResponse.class);

                    beginIndex = videoInfo.indexOf("<title>");
                    endIndex = videoInfo.indexOf("|", beginIndex + 7);
                    info.title = videoInfo.substring(beginIndex + 7, endIndex - 1);

                    for (JSONArgsResponse detail : jsonObj.htmlStreams) {
                        info.urls
                                .put("video/mp4:" + ("standard".equals(detail.id) ? "medium" : "large"), detail.file);
                    }

                    beginIndex = videoInfo.indexOf("<a id=\"no-flash-video-download\" href=\"");
                    endIndex = videoInfo.indexOf("\">",
                            beginIndex + "<a id=\"no-flash-video-download\" href=\"".length());
                    info.urls.put("video/mp4:low", videoInfo.substring(beginIndex
                            + "<a id=\"no-flash-video-download\" href=\"".length(), endIndex));
                }
            }

            info.sizes = new HashMap<String, Integer>();
            for (String quality : info.urls.keySet()) {
                String url = info.urls.get(quality);
                info.sizes.put(quality, getFileSize(url));
            }

            Map<String, String> result = new HashMap<String, String>();
            for (String quality : info.sizes.keySet()) {
                result.put(quality, humanReadableByteCount(info.sizes.get(quality), true));
            }

            return result;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
